home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / master / Examples / Visual / VMake / process.c < prev    next >
C/C++ Source or Header  |  1994-02-01  |  12KB  |  332 lines

  1. #include "vmake.h"
  2. #include <dos/dostags.h>
  3.  
  4. Prototype int InitSession(void);
  5. Prototype void TermSession(void);
  6. Prototype void PostLog(char *msg);
  7. Prototype int IssueCommand(char *cmd);
  8. Prototype int setup_cli(void);
  9.  
  10. /******************************************************************************/
  11. static APTR    pr_ConsoleTask;  /* Console handler process for current window */
  12.  
  13. static BPTR    Outfh;           /* Filehandle for session output              */
  14. static BPTR    Sesfh;           /* Filehandle for session Input/Output        */
  15. static LONG    cli_Interactive; /* Boolean; True if prompts required          */
  16. static LONG    cli_Background;  /* Boolean; True if CLI created by RUN        */
  17.  
  18. static struct Process *SesProcess;
  19. /******************************************************************************/
  20.  
  21. /***********************************************************************************
  22.  * Procedure: InitSession
  23.  * Synopsis:  rc = InitSession()FreeVec(vec);
  24.  * Purpose:   This code returns a vector to storage
  25.  ***********************************************************************************/
  26. int InitSession()
  27. {
  28.    struct FileHandle *handle;
  29.    struct CommandLineInterface *cli;
  30.  
  31.    if (!Sesfh)
  32.    {
  33. char cbuf[256];
  34.       SesProcess = (struct Process *)FindTask(0);
  35.       cli = BADDR(SesProcess->pr_CLI);
  36.  
  37.       /* Save the current console and background status information */
  38.       pr_ConsoleTask = SesProcess->pr_ConsoleTask;
  39.  
  40.       cli_Interactive    = cli->cli_Interactive;
  41.       cli_Background     = cli->cli_Background;
  42.  
  43.       /* Open up our console to do the work */
  44.       if (!build_command(cbuf, 255, global.text[CONFIG_CONSOLE], 0))
  45.          /* JAT's usual inverted logic... */
  46.          Sesfh = Open(cbuf, MODE_OLDFILE);
  47.       else
  48.          /* error message (since we don't knowwhat build_command() produced */
  49.          strcpy(cbuf, global.text[CONFIG_CONSOLE]);
  50.       if (Sesfh == NULL) 
  51.       {
  52.          Sesfh = Open("Con:0/0/320/100/Vmake_Default/Auto", MODE_OLDFILE);
  53.          if (Sesfh == NULL)
  54.             /* nowhere to put an error message, give up */
  55.             return(1);
  56.          else
  57.          {
  58.             char buf[256];
  59.             
  60.             sprintf(buf, "Bad Console \"%s\" from file: %s\n", 
  61.                     cbuf, Sym_Lookup(SYM_CONFIG));
  62.             PostLog(buf);
  63.          }
  64.       }
  65.       handle = (struct FileHandle *)(Sesfh << 2);
  66.       SesProcess->pr_CIS = SesProcess->pr_COS = Sesfh;
  67.  
  68.       SesProcess->pr_ConsoleTask = (APTR)handle->fh_Type;
  69.  
  70.       if (DOSBase->dl_lib.lib_Version >= 36)
  71.          Outfh = Open("*", MODE_NEWFILE);
  72.  
  73.       cli->cli_Interactive    = DOSTRUE;
  74.       cli->cli_Background     = DOSFALSE;
  75.       atexit(TermSession);
  76.    }
  77.    return(0);
  78. }
  79.  
  80. /***********************************************************************************
  81.  * Procedure: TermSession
  82.  * Synopsis:  (void)TermSession();
  83.  * Purpose:   Terminate usage of the Session
  84.  ***********************************************************************************/
  85. void TermSession()
  86. {
  87.    struct CommandLineInterface *cli;
  88.    if (Sesfh)
  89.    {
  90.       cli = BADDR(SesProcess->pr_CLI);
  91.  
  92.       Close(Sesfh);
  93.       if (Outfh) Close(Outfh);
  94.       Sesfh = Outfh = 0;
  95.       SesProcess->pr_ConsoleTask = pr_ConsoleTask;
  96.       cli->cli_Interactive       = cli_Interactive;
  97.       cli->cli_Background        = cli_Background;
  98.    }
  99. }
  100.  
  101. /***********************************************************************************
  102.  * Procedure: PostLog
  103.  * Synopsis:  (void)PostLog(message);
  104.  * Purpose:   Output a message to the session log
  105.  ***********************************************************************************/
  106. void PostLog(char *msg)
  107. {
  108.    if (!InitSession())
  109.    {
  110.       Write(Sesfh, msg, strlen(msg));
  111.       Write(Sesfh, "\n", 1);
  112.    }
  113. }
  114.  
  115.  
  116. /***********************************************************************************
  117.  * Procedure: IssueCommand
  118.  * Synopsis:  rc = IssueCommand(cmd);
  119.  * Purpose:   Execute a given command with the current console
  120.  ***********************************************************************************/
  121. int IssueCommand(char *cmd)
  122. {
  123.    int rc;
  124.    struct TagItem taglist[4];
  125.  
  126.    rc = InitSession();
  127.    if (!rc)
  128.    {
  129.       if (Outfh)
  130.       {
  131.          taglist[0].ti_Tag  = SYS_UserShell;
  132.          taglist[0].ti_Data = 1;
  133.          taglist[1].ti_Tag  = SYS_Input;
  134.          taglist[1].ti_Data = (ULONG)Sesfh;
  135.          taglist[2].ti_Tag  = SYS_Output;
  136.          taglist[2].ti_Data = (ULONG)Outfh;
  137.          taglist[3].ti_Tag  = TAG_DONE;
  138.  
  139.          rc = SystemTagList(cmd, taglist);
  140.       }
  141.       else
  142.       {
  143.          rc = Execute(cmd, 0L, Sesfh);
  144.       }
  145.    }
  146.    return(rc);
  147. }
  148.  
  149. /***********************************************************************************
  150.  * Procedure: Alloc_Vec
  151.  * Synopsis:  newvec = Alloc_Vec(size);
  152.  * Purpose:   This code allocates a DOS vector
  153.  * Note:      This storage is NOT automatically freed by the compiler library.
  154.  ***********************************************************************************/
  155. static BPTR Alloc_Vec(int size)
  156. {
  157.    long *new;
  158.  
  159.    size += 4;
  160.    /* Based on the given size, allocate the right amount of memory */
  161.    new = (long *)AllocMem(size, MEMF_PUBLIC | MEMF_CLEAR);
  162.  
  163.    if (new != NULL)
  164.    {
  165.       /* Remember to point one past the length longword */
  166.       *new++ = size;
  167.    }
  168.    else
  169.    {
  170.       request(1, TEXT_NOMEM, NULL, NULL);
  171.    }
  172.    return(MKBADDR(new));
  173. }
  174.  
  175. /***********************************************************************************
  176.  * Procedure: Free_Vec
  177.  * Synopsis:  (void)FreeVec(vec);
  178.  * Purpose:   This code returns a vector to storage
  179.  ***********************************************************************************/
  180. static void Free_Vec(BPTR orig)
  181. {
  182.    long *in;
  183.  
  184.    in = (long *)BADDR(orig);
  185.    in--;  /* Back up to the size information for the original allocation */
  186.  
  187.    /* Based on the given size, allocate the right amount of memory */
  188.    FreeMem(in, *in);
  189. }
  190.  
  191. /* This structure maps a DOS Path entry.  This is not really documented in any */
  192. /* of the DOS include files but is generally understood                        */
  193. /* Note that it must allocated as a dos vector (length byte in front of it)    */
  194. struct PathEnt {
  195.   BPTR nextent;
  196.   BPTR lock;
  197. };
  198.  
  199. /***********************************************************************************
  200.  * Procedure: freecli
  201.  * Synopsis:  (void)freecli();
  202.  * Purpose:   This code frees up any CLI allocated structures.
  203.  * Note:      This routine is only called as an autoexit routine when setup_cli
  204.  *            has done some work.  Otherwise we assume that no special work had to
  205.  *            be done to make things happen.
  206.  ***********************************************************************************/
  207. static void freecli()
  208. {
  209.    struct CommandLineInterface *cli;
  210.    BPTR oldent;
  211.  
  212.    cli = BADDR(SesProcess->pr_CLI);
  213.  
  214.    if (!cli) return;
  215.  
  216.    /* We only need to free the 4 vectors we created and all of the */
  217.    /* locks on the the path list.                                  */
  218.    Free_Vec(cli->cli_SetName);
  219.    Free_Vec(cli->cli_CommandName);
  220.    Free_Vec(cli->cli_Prompt);
  221.    Free_Vec(cli->cli_CommandFile);
  222.  
  223.    while((oldent = cli->cli_CommandDir) != 0)
  224.    {
  225.       struct PathEnt *pathent;
  226.  
  227.       /* First we need to remove us from the path list */
  228.       pathent = BADDR(oldent);
  229.       cli->cli_CommandDir = pathent->nextent;
  230.       UnLock(pathent->lock);     /* Free the lock at this entry        */
  231.       Free_Vec(oldent);          /* Free the storage for the path node */
  232.    }
  233.    SesProcess->pr_CLI = 0;
  234. }
  235.  
  236. /***********************************************************************************
  237.  * Procedure: setup_cli()
  238.  * Synopsis:  (void)setup_cli();
  239.  * Purpose:   This code sets up a fake CLI structure by copying the appropriate
  240.  *            information from workbench.  It will prepare for that to be
  241.  *            automatically be freed on program termination through freecli.
  242.  ***********************************************************************************/
  243. int setup_cli()
  244. {
  245.    struct CommandLineInterface *cli, *wbcli;
  246.    struct Process *wbproc;
  247.    struct PathEnt *pathent, *wbent;
  248.  
  249.    SesProcess = (struct Process *)FindTask(0);
  250.  
  251.    /* Allocate a CLI structure if we need one                        */
  252.    if (SesProcess->pr_CLI) return;
  253.  
  254.    cli = get_mem(sizeof(struct CommandLineInterface));
  255.    if (cli == NULL) return(1);
  256.  
  257.    atexit(freecli);
  258.  
  259.    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  260.    /* Next we need to go through and copy the workbench path over to      */
  261.    /* Our process.  The only things we need to duplicate are:             */
  262.    /*                                                                     */
  263.    /* We need to copy over the BPTR link list for this one.               */
  264.    /*    pr_CLI->cli_CommandDir   Head of the path locklist               */
  265.    /*                                                                     */
  266.    /* These are buffers which we need to allocate space for and clone     */
  267.    /*    pr_CLI->cli_SetName      Name of current directory               */
  268.    /*    pr_CLI->cli_CommandName  Name of current command                 */
  269.    /*    pr_CLI->cli_Prompt       Current prompt (set by PROMPT)          */
  270.    /*    pr_CLI->cli_CommandFile  Name of EXECUTE command file            */
  271.    /*                                                                     */
  272.    /* These fields are just copied over verbatim                          */
  273.    /*    pr_CLI->cli_FailLevel    Fail level (set by FAILAT)              */
  274.    /*    pr_CLI->cli_Interactive  Boolean; True if prompts required       */
  275.    /*    pr_CLI->cli_Background   Boolean; True if CLI created by RUN     */
  276.    /*    pr_CLI->cli_DefaultStack Stack size to be obtained in long words */
  277.    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  278.    SesProcess->pr_CLI = MKBADDR(cli);
  279.  
  280.    /* Now we need to find the workbench CLI */
  281.    if ( ( (wbproc = (struct Process *)FindTask("Workbench")) == NULL) &&
  282.         ( (wbproc = (struct Process *)FindTask("Fastbench")) == NULL) )
  283.    {
  284.       /* For some reason workbench and FastBench are not in the system */
  285.       /* We need to punt and not let them really do any work           */
  286.       return(2);
  287.    }
  288.    wbcli = BADDR(wbproc->pr_CLI);
  289.  
  290.    /* Say what??  We have a workbench but it doesn't have a CLI???   */
  291.    if (wbcli == NULL) return(3);
  292.  
  293.    /* Do all of the staight copies from the Workbench CLI */
  294.    cli->cli_FailLevel    = 20;
  295.    cli->cli_Interactive  = DOSFALSE;
  296.    cli->cli_Background   = DOSFALSE;
  297.    cli->cli_DefaultStack = 2048; /* Longwords */
  298.  
  299.    /* Next we get all of the cloned vector buffers */
  300.    cli->cli_SetName      = Alloc_Vec( 80);  /* These numbers are truely magic  */
  301.    cli->cli_CommandName  = Alloc_Vec(104);  /* and CAN NOT be changed for true */
  302.    cli->cli_Prompt       = Alloc_Vec( 60);  /* compatibility with 1.3.         */
  303.    cli->cli_CommandFile  = Alloc_Vec( 40);  /* Don't even try to change them   */
  304.  
  305.    /* Lastly we need to copy over all of the paths from workbench */
  306.    if (wbcli->cli_CommandDir)
  307.    {
  308.       /* Start out the process by copying over the first vector */
  309.       cli->cli_CommandDir = Alloc_Vec(8);
  310.       wbent   = BADDR(wbcli->cli_CommandDir);
  311.       pathent = BADDR(cli->cli_CommandDir);
  312.  
  313.       /* Now loop through copying over the vector and then replacing everything */
  314.       /* in place.  This looks a little strange because we are actually counting */
  315.       /* on creating a structure with a pointer to the other linked list, but  */
  316.       while(wbent->nextent)
  317.       {
  318.          pathent->nextent = Alloc_Vec(8);
  319.          pathent->lock = DupLock(wbent->lock);
  320.          if (!pathent->lock)
  321.          {
  322.             pathent->nextent = 0;  /* Make sure we terminate the list here */
  323.             return(4);
  324.          }
  325.          wbent   = BADDR(wbent->nextent);
  326.          pathent = BADDR(pathent->nextent);
  327.       }
  328.       pathent->lock = DupLock(wbent->lock);
  329.       if (!pathent->lock) return(5);
  330.    }
  331. }
  332.